/*
 * @Author: 杰编程 2306248989@qq.com
 * @Date: 2023-08-06 15:30:54
 * @LastEditors: 杰编程 2306248989@qq.com
 * @LastEditTime: 2023-08-06 15:47:17
 * @FilePath: /lesson25/tcp/daemon.hpp
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#pragma once

#include <cstdlib>
#include <cstring>
#include <signal.h>
#include <unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include "log.hpp"
#include "err.hpp"

//守护进程的本质：孤儿进程
void Daemon()
{
    // 1. 忽略异常信号
    signal(SIGCHLD, SIG_IGN);
    signal(SIGPIPE, SIG_IGN);
    // 2. 创建子进程，让子进程成为新的会话
    if (fork() > 0)
        exit(0); // 父进程退出
    // 子进程
    // 3. 设置子进程为新会话
    pid_t id = setsid();
    if (id < 0)
    {
        logMessage(Fatal, "setsid error:%s\n", strerror(errno));
        exit(SETSID_ERR);
    }
    logMessage(Info, "setsid successful.\n");
    //4. 可选，更改工作目录
    //chdir("/");

    //5. 处理0,1,2的问题
    int fd=open("/dev/null",O_RDWR);
    if(fd<0)
    {
        logMessage(Fatal,"open /dev/null error:%s\n",strerror(errno));
        exit(OPEN_ERR);
    }
    logMessage(Info,"open /dev/null successful!\n");
    dup2(fd,0);
    dup2(fd,1);
    dup2(fd,2);
    close(fd);
}